#include"rational.h"
#include<algorithm>

Rational::Rational (int a){
	num = a;
	den = 1;
}

Rational::Rational (int a, int b){
	num = a;
	den = b;
	cancel();
}

Rational::Rational (const Rational & a){
	num = a.num;
	den = a.den;
}

Rational & Rational::operator= (const Rational & a){
	Rational tmp(a);
	swap(tmp);
	return *this;
}

Rational & Rational::operator*= (const Rational & a){
	num *= a.num;
	den *= a.den;
	cancel();
	return *this;
}

Rational & Rational::operator+= (const Rational & a){
	num = num *  a.den + a.num * den;
	den = den * a.den;
	cancel();
	return *this;
}

Rational & Rational::operator-= (const Rational & a){
	num = num * a.den - a.num * den;
	den = den * a.den;
	cancel();
	return *this;
}

Rational & Rational::operator/= (const Rational & a){
	*this *= Rational(a.den, a.num);
	cancel();
	return *this;
}

Rational::operator double () const{
	return double(num) / den;
}

Rational & Rational::operator++ (){	//prefix
	num += den;
	cancel();
	return *this;
}

Rational Rational::operator++ (int unused){	//postfix
	Rational tmp(*this);
	++(*this);
	return tmp;
}

Rational & Rational::operator-- (){	//prefix
	num -= den;
	cancel();
	return *this;
}

Rational Rational::operator-- (int unused){	//postfix
	Rational tmp(*this);
	--(*this);
	return tmp;
}

void Rational::swap (Rational & a){
	std::swap(num, a.num);
	std::swap(den, a.den);
}

static int gcd (int a, int b){
	if (b == 0){
	return a;
	}
	return gcd(b, a % b);
}

void Rational::cancel (){
	int d = gcd(std::abs(num), std::abs(den));
	num /= d;
	den /= d;
	if (den < 0){
		den *= -1;
		num	*= -1;
	}
}

bool operator== (const Rational & a, const Rational & b){
	return (a.num == b.num && a.den == b.den);
}

bool operator!= (const Rational & a, const Rational & b ){
	return !(a == b);
}

bool operator< (const Rational & a, const Rational & b){
	return (a.num * b.den < b.num * a.den);
}

bool operator> (const Rational & a, const Rational & b){
	return !(a < b || a == b);
}

bool operator<= (const Rational & a, const Rational & b){
	return !(a > b);
}

bool operator>= (const Rational & a, const Rational & b){
	return !(a < b);
}

Rational operator+ (const Rational & a, const Rational & b){
	Rational tmp = a;
	tmp += b;
	return tmp;
}

Rational operator- (const Rational & a, const Rational & b){
	Rational tmp = a;
	tmp -= b;
	return tmp;
}

Rational operator- (const Rational & a){
	Rational tmp = a;
	tmp.num *= -1;
	return tmp;
}

Rational operator* (const Rational & a, const Rational & b){
	Rational tmp(a);
	tmp *= b;
	return tmp;
}

Rational operator/ (const Rational & a, const Rational & b){
	Rational tmp(a);
	tmp /= b;
	return tmp;
}
